package sv.com.compassion.servicio;

import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import sv.com.compassion.dao.GenericoDAO;
import java.util.List;

/** Implementación de los métodos de la interface GenericoDAO
* @author grupo de Tesis
*/

@Transactional
public class GenericoDAOImpl implements GenericoDAO {
    private EntityManager em;
/** 
* Administrador de las entidades
*/
    @PersistenceContext
    public void setEntityManager(EntityManager em) {
        this.em = em;
    }
/** 
* @param  entidad tipo Object
* Guarda el objeto que se recibe de parámetro.
*/
    @Override
    public void save(Object entidad) {
        em.persist(entidad);
    }
/** 
* @param  entidad tipo Object
* Elimina (DELETE) el objeto que se recibe de parámetro.
*/
    @Override
    public void delete(Object entidad) {
        em.remove(entidad);
    }
/**
* @param query tipo String, se recibe el String de la consulta; 
* @param maxResult tipo Integer, se recibe el número rango superior de los registros;
* @param firstElement tipo Integer, se recibe el rango inferior de registros;
* Método para realizar consultas.
* @return  list objeto tipo Lista.
* 
*/
    @Override
    public List find(String query, Integer maxResult, Integer firstElement) {
        List list;
        Query q; 
        q = em.createQuery(query);
        if(maxResult != null && firstElement != null){
            q.setMaxResults(maxResult);
            q .setFirstResult(firstElement);
        }
        list = q.getResultList();
        return list;
     }
/**
 * @param query de tipo String
 * Contar los registros que cumplan con los filtros de la consulta. 
 * @return un número de tipo Integer que lleva el count que regreso la consulta
 */
    @Override
    public Integer countRow(String query){
        return ((Long)em.createQuery(query).getSingleResult()).intValue();
    }
/**
     * @param query de tipo String con la consulta.
     * @param maxResult tipo Integer, se recibe el número rango superior de los registros; 
     * @param firstElement tipo Integer, se recibe el rango inferior de registros;
     * Método utilizado para consultas nativas es decir donde no se utilicen los objetos mapeados
     * @return 
     */
    @Override
    public List queryNative(String query, Integer maxResult, Integer firstElement) {
        List list;
        Query q;
        q = em.createNativeQuery(query);
        if(maxResult != null && firstElement != null){
            q.setMaxResults(maxResult);
            q.setFirstResult(firstElement);
        }
        list = q.getResultList();
        return list;
    }
/**
     * @param query de tipo String, esté posee la consulta con el count que se ejecutara.
     * @return un valor Integer con el resultado del count
     */
    @Override
    public Integer countRowQueryNative(String query) {
        return ((Long)em.createNativeQuery(query).getSingleResult()).intValue();
    }
/**
 * @param entidad de tipo Object por medio de este objeto generico se recibe el objeto a actualizar.
 */
    @Override
    public void update(Object entidad) {
        em.merge(entidad);
    }
        
}
